﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using LaughingDog.GameObjects;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace LaughingDog.Components
{
    public class Camera : Behaviour
    {
        /// <summary>
        /// Enumeration of all available origin points for a Camera component.
        /// </summary>
        public enum CameraOrigins { Centre, TopLeft, BottomLeft, TopRight, BottomRight }

        private static Camera mActiveCamera = null;

        private CameraOrigins mCameraOrigin = CameraOrigins.Centre;
        private Matrix mTransformationMatrix;
        private Single mZoom = 1;

        /// <summary>
        /// Gets or sets the current active Camera.
        /// </summary>
        public static Camera ActiveCamera { get { return mActiveCamera; } set { mActiveCamera = value; } }

        /// <summary>
        /// Gets this Cameras transformation matrix.
        /// </summary>
        public Matrix TransformationMatrix { get { return mTransformationMatrix; } }

        /// <summary>
        /// Gets or sets the current origin type of the camera.
        /// </summary>
        //public CameraOrigins CameraOrigin { get { return mCameraOrigin; } set { mCameraOrigin = value; } }

        /// <summary>
        /// Gets or sets the amount of zoom that should be applied to this Camera.
        /// </summary>
        public Single Zoom
        {
            get { return mZoom; }
            set { mZoom = value; if (mZoom < 0.1f) mZoom = 0.1f; } // Negative zoom will flip image
        }        

        /// <summary>
        /// Creates a new instance of a Camera component.
        /// </summary>
        /// <param name="gameObject">The GameObject that this component should be attached to.</param>
        public Camera(GameObject gameObject)
            : base(gameObject)
        {
        }
       
        /// <summary>
        /// Updates this Camera.
        /// </summary>
        public override void Update()
        {
            updateTransformationMatrix();

            base.Update();
        }

        private void updateTransformationMatrix()
        {
            Matrix translationMatrix = new Matrix();
            switch (mCameraOrigin)
            {
                case CameraOrigins.Centre:

                    translationMatrix = Matrix.CreateTranslation(new Vector3(Screen.Width * 0.5f, Screen.Height * 0.5f, 0));                  

                    break;
                case CameraOrigins.TopLeft:

                    translationMatrix = Matrix.CreateTranslation(new Vector3(0, 0, 0));                  

                    break;
                case CameraOrigins.TopRight:

                    translationMatrix = Matrix.CreateTranslation(new Vector3(Screen.Width, 0, 0));                  

                    break;
                case CameraOrigins.BottomLeft:

                    translationMatrix = Matrix.CreateTranslation(new Vector3(0, Screen.Height, 0));                  

                    break;
                case CameraOrigins.BottomRight:

                    translationMatrix = Matrix.CreateTranslation(new Vector3(Screen.Width, Screen.Height, 0));                  

                    break;
                default:
                    break;
            }

            mTransformationMatrix = Matrix.CreateTranslation(new Vector3(-Transform.Position.X, -Transform.Position.Y, 0)) *
                                    Matrix.CreateRotationZ(Transform.RotationRadians) *
                                    Matrix.CreateScale(new Vector3(Zoom, Zoom, 0)) *
                                    translationMatrix;
        }

        //public bool IsInView(GameObject gameObject)
        //{
        //    // If the object is not within the horizontal bounds of the screen

        //    if ((gameObject.Transform.Position.X + gameObject.Transform.Size.X) < (Transform.Position.X - mOrigin.X) || (gameObject.Transform.Position.X) > (Transform.Position.X + mOrigin.X))
        //        return false;

        //    // If the object is not within the vertical bounds of the screen
        //    if ((gameObject.Transform.Position.Y + gameObject.Transform.Size.Y) < (Transform.Position.Y - mOrigin.Y) || (gameObject.Transform.Position.Y) > (Transform.Position.Y + mOrigin.Y))
        //        return false;

        //    // In View
        //    return true;
        //}
    }
}
